use crate::core::base_node::NodeStatus;
use crate::core::action;
use core::base_node::{BaseNode, NodeData, TBaseNode, BLACKBOARD_MEM_RUNNING_CHILD};
use core::behavior_tree::NodeTypeRegister;
use std::collections::HashMap;
use core::tick::Tick;

pub struct Sequence {
    base_node: NodeData<BaseNode>,
    children: Vec<Box<TBaseNode>>
}
impl Sequence {
    fn new(config: serde_json::Value)->Result<Sequence, String> {
        match BaseNode::new(config) {
            Ok(_n) => {
                Ok(Sequence {
                    base_node: NodeData::new(_n),
                    children: Vec::new()
                })
            }
            Err(_e) => {
                Err(_e)
            }
        }
    }
    pub fn register(container: &mut NodeTypeRegister, name: String) {
        container.register_type(name, Box::new(|config: serde_json::Value, nodes: &mut HashMap<String, Box<dyn TBaseNode>>| {
            match Sequence::new(config) {
                Ok(_n) => {
                    nodes.insert(_n.base_node.id.to_string(), Box::new(_n));
                }
                Err(_e) => {}
            };
        }));
    }
}
impl TBaseNode for Sequence {
    fn get_base_node_ref(&self) -> NodeData<BaseNode> {
        self.base_node.clone()
    }
    fn add_child(&mut self, child: Box<TBaseNode>) {
        self.children.push(child)
    }
    fn execute(&self, tick: &mut Tick) -> NodeStatus {
        BaseNode::_execute(self.base_node.clone(), tick, self)
    }

    fn tick(&self, tick: &mut Tick) -> NodeStatus {
        for index in 0..self.children.len() {
            let child: &Box<dyn TBaseNode> = unsafe {
                self.children.get_unchecked(index)
            };
            let status = child.execute(tick);
            if status != NodeStatus::SUCCESS {
                return status;
            }
        }
        NodeStatus::SUCCESS
    }
}